package com.example.app.manager.c2;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.Face;
import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.util.Range;
import android.util.Size;
import android.view.MotionEvent;
import android.view.Surface;

import com.example.app.activity.MLog;
import com.example.app.manager.MediaRecorderManager;

import java.util.Arrays;

/**
 * 相机管理 5.0 以上系统用
 * Created by 郭敏 on 2018/3/21 0021.
 */
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
class Camera2Base {
    private String tag = "Camera2Base";

    private Context context;
    //false 前置摄像头 true 后置相机
    private boolean isCameraBack = false;
    //true： 开启是开启的 ，false： 灯光是关闭的
    private boolean isLight;
    //相机参数
    private CameraCharacteristics cameraCharacter;
    //预览大小
    private Size previewSize;
    //设备
    private CameraManager cameraManager;
    private CameraDevice cameraDevice;
    private CaptureRequest.Builder previewBuilder;
    private CaptureRequest previewRequest;
    private CameraCaptureSession cameraSession;
    //
    //不影响ui的线程
    private HandlerThread backgroundThread;
    //在后台运行任务。
    private HandlerCamera backgroundHandler;


    /**
     * 开启线程
     */
    protected void onOpenThread() {
        if (backgroundHandler != null) {
            return;
        }
        backgroundThread = new HandlerThread("CameraBackground");
        backgroundThread.start();
        backgroundHandler = new HandlerCamera(backgroundThread.getLooper());

    }

    /**
     * 关闭线程
     */
    protected void onCloseThread() {
        try {
            if (backgroundThread != null) {
                backgroundThread.quitSafely();
                backgroundThread.join();
            }
            if (backgroundHandler != null) {
                backgroundHandler.removeCallbacksAndMessages(null);
            }
            backgroundThread = null;
            backgroundHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //相机数量
    int cameraCount = -1;
    private boolean hasBack, hasFront, hasExternal;

    //获取摄像头数量
    private void initCameraCount() {
        if (cameraCount > -1) {
            return;
        }
        cameraCount = 0;
        //遍历所有摄像头
        try {
            String[] ids = cameraManager.getCameraIdList();
            for (String cameraId : ids) {
                CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
                Integer type = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (type == null) {
                    continue;
                }
                //后置摄像头
                if (type == CameraCharacteristics.LENS_FACING_FRONT) {
                    cameraCount += 1;
                    hasFront = true;
                    d("后置摄像头");
                    continue;
                }
                //前置摄像头
                if (type == CameraCharacteristics.LENS_FACING_BACK) {
                    cameraCount += 1;
                    hasBack = true;
                    d("前置摄像头");
                    continue;
                }
                //双摄像头
                if (type == CameraCharacteristics.LENS_FACING_EXTERNAL) {
                    cameraCount += 1;
                    hasExternal = true;
                    d("双摄像头");
                    continue;
                }
                break;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }


    }

    protected int getCameraCount() {
        return cameraCount;
    }

    //是否开启了相机 true 开启
    protected boolean isOpne() {
        return cameraDevice != null;
    }

    private String getCameraId() {
        String cameraID = "";
        //默认打开前置摄像头
        if (!isCameraBack && hasFront) {
            //前置摄像头
            cameraID = "" + CameraCharacteristics.LENS_FACING_FRONT;
        }
        if (isCameraBack && hasBack) {
            //后置摄像头
            cameraID = "" + CameraCharacteristics.LENS_FACING_BACK;
        }
        return cameraID;
    }

    protected void initCamera(Context context) {
        initData();
        this.context = context;
        cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
        initCameraCount();
        //后摄像头
        String cameraID = getCameraId();
        if (TextUtils.isEmpty(cameraID)) {
            d("获取摄像头失败");
            return;
        }
        isVideoFous = false;
        //
        try {
            cameraCharacter = cameraManager.getCameraCharacteristics(cameraID);
            StreamConfigurationMap map = cameraCharacter.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            double exposureCompensationSteps = cameraCharacter.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP)
                    .doubleValue();
            d("曝光补偿：" + exposureCompensationSteps);
            int exposureCompensation = (int) (2.0 / exposureCompensationSteps);

            previewSize = selectPreviewSize(map.getOutputSizes(SurfaceTexture.class));
            if (previewSize == null) {
                onCameraError(1, "获取对应的相机尺寸失败");
                return;
            }
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                onCameraError(2, "没有相机权限");
                return;
            }
            cameraManager.openCamera(cameraID, new StateCallback(), backgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
            onCameraError(3, "相机开启失败:" + e.getMessage());
        }

    }

    //获取预览控件的宽和高
    protected int[] getPreviewWH() {
        return null;
    }

    //获取 预览大小
    protected Size getPreviewSize() {
        return previewSize;
    }

    protected boolean isLight() {
        return isLight;
    }

    //1:获取对应的相机尺寸失败
    //2:没有相机权限
    //3:相机开启失败
    //4:预览失败
    protected void onCameraError(int type, String msg) {
        d(type + msg);
    }

    protected CameraCharacteristics getCameraCharacter() {
        return cameraCharacter;
    }

    //获取合适的预览大小
    private Size selectPreviewSize(Size[] choices) {
        //相机镜头
        Size cameraLensSize = null;
        //
        int[] sizes = getPreviewWH();
        if (sizes == null || sizes.length < 2) {
            return null;
        }
        int previewMin = Math.min(sizes[0], sizes[1]);
        int previewMax = Math.max(sizes[0], sizes[1]);
        int px = previewMin * previewMax;
        double fixationD = (double) previewMin / (double) previewMax;
        double difference = -1;
        d("previewMin：" + previewMin + " previewMax:" + previewMax + " fixation:" + fixationD);
        for (Size size : choices) {
            int w = size.getWidth();
            int h = size.getHeight();
            double max = Math.max(w, h);
            double min = Math.min(w, h);
            double d = min / max;
            d("预览大小列表 Width：" + w + " Height:" + h + " d:" + d);
            if (cameraLensSize == null) {
                cameraLensSize = size;
                difference = d;
                continue;
            }
            max = Math.max(fixationD, d);
            min = Math.min(fixationD, d);
            double f = min / max;
            if (f == 1 && difference != 1) {
                cameraLensSize = size;
                difference = 1;
                continue;
            }
            int s = cameraLensSize.getHeight() * cameraLensSize.getWidth();
            if (f == 1 && difference == 1) {
                if (px == (w * h)) {
                    cameraLensSize = size;
                    difference = 1;
                    break;
                }
                if (s < (w * h)) {
                    cameraLensSize = size;
                    difference = 1;
                }
                continue;
            }
            f = Math.abs(f - d);
            if (difference < 1 && difference > f) {
                cameraLensSize = size;
                difference = f;
                continue;
            }
            if (difference < 1 && difference == f && s < (w * h)) {
                cameraLensSize = size;
                difference = f;
                continue;
            }

        }
        d("合适的预览大小 Width：" + cameraLensSize.getWidth() + " Height:" + cameraLensSize.getHeight());
        return cameraLensSize;
    }


    private Surface previewSurface;

    //获取预览的 Surface
    private Surface getSurface() {
        if (previewSurface != null) {
            return previewSurface;
        }
        previewSurface = getPreviewSurface(previewSize);
        return previewSurface;
    }

    protected Surface getPreviewSurface(Size previewSize) {
        return null;
    }

    //关闭相机
    protected void onCameraClose() {
        isLight = false;
        isCameraBack = false;
        if (cameraTakePhoto != null) {
            cameraTakePhoto.onClose();
            cameraTakePhoto = null;
        }
        if (cameraRecordVideo != null) {
            cameraRecordVideo = null;
        }
        if (previewSurface != null) {
            previewSurface = null;
        }
        if (previewBuilder != null) {
            previewBuilder = null;
        }
        if (previewRequest != null) {
            previewRequest = null;
        }
        if (cameraSession != null) {
            cameraSession.close();
            cameraSession = null;
        }
        if (cameraDevice != null) {
            cameraDevice.close();
            cameraDevice = null;
        }
        if (cameraManager != null) {
            cameraManager = null;
        }

    }

    private void closeSession() {
        if (cameraSession == null) {
            return;
        }
        cameraSession.close();
        cameraSession = null;
    }

    //重新预览
    protected void setResetPreview(Context context) {
        if (cameraDevice != null) {
            initData();
            //构建失能AF的请求
            previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            //继续开启预览
            try {
                cameraSession.setRepeatingRequest(previewRequest, null, backgroundHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
            return;
        }
        initCamera(context);
    }

    //==========================相机功能=============================================
    //手指按下的点为(x1, y1)手指离开屏幕的点为(x2, y2)
    private float fingerSpacing;
    private int zoomLevel = 0;
    private Rect zoom;

    //重置数据
    private void initData() {
        zoomLevel = 0;
        fingerSpacing = 0;
        zoom = null;
    }

    //相机缩放
    protected void onCameraZoom(MotionEvent event) {
        //活动区域宽度和作物区域宽度之比和活动区域高度和作物区域高度之比的最大比率
        float maxZoom = (cameraCharacter.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)) * 10;
        Rect m = cameraCharacter.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
        //计算两个触摸点的距离
        float currentFingerSpacing = getFingerSpacing(event);
        if (fingerSpacing != 0) {
            if (currentFingerSpacing > fingerSpacing && maxZoom > zoomLevel) {
                zoomLevel++;

            } else if (currentFingerSpacing < fingerSpacing && zoomLevel > 1) {
                zoomLevel--;
            }
            if (zoomLevel > maxZoom) {
                zoomLevel = (int) maxZoom;
            }
            if (zoomLevel < 0) {
                zoomLevel = 0;
            }
            int minW = (int) (m.width() / maxZoom);
            int minH = (int) (m.height() / maxZoom);
            int difW = m.width() - minW;
            int difH = m.height() - minH;
            int cropW = difW / 100 * zoomLevel;
            int cropH = difH / 100 * zoomLevel;
            cropW -= cropW & 3;
            cropH -= cropH & 3;
            zoom = new Rect(cropW, cropH, m.width() - cropW, m.height() - cropH);
            previewBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
        }
        fingerSpacing = currentFingerSpacing;
        try {
            cameraSession.setRepeatingRequest(previewBuilder.build(), null, backgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
            MLog.e("缩放失败", e.getMessage());
        }
    }

    //计算两个触摸点的距离
    private float getFingerSpacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    //相机聚焦
    protected void onCameraFocus(Rect rect) {
        d("相机聚焦" + " left=" + rect.left + " right=" + rect.right +
                " top=" + rect.top + " bottom=" + rect.bottom);
        //聚焦区
        MeteringRectangle[] af = new MeteringRectangle[]{new MeteringRectangle(rect, MeteringRectangle.METERING_WEIGHT_MIN)};
        previewBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, af);
        //曝光区
        MeteringRectangle[] ae = new MeteringRectangle[]{new MeteringRectangle(rect, MeteringRectangle.METERING_WEIGHT_MAX)};
        previewBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, ae);
        //聚焦
        onAutoFocus(true);
        //设置对焦
        previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
        //手动聚焦一般用 CONTROL_AF_MODE_AUTO
        previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
        try {
            cameraSession.setRepeatingRequest(previewBuilder.build(), null, backgroundHandler);
            //cameraSession.setRepeatingRequest(previewBuilder.build(), focusCallback, backgroundHandler);
        } catch (CameraAccessException e) {
            d("相机聚焦失败:" + e.getMessage());
        }
        //触发对焦
        previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
        try {
            //触发对焦通过capture发送请求, 因为用户点击屏幕后只需触发一次对焦
            cameraSession.capture(previewBuilder.build(), null, backgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
            d("相机聚焦失败:" + e.getMessage());
        }
    }

    //自动聚焦
    private void onAutoFocus(boolean isClose) {
        if (isClose) {
            //关闭自动对焦
            previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_OFF);
            previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF);
            //previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
            //previewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
            //previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            //previewBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);
            return;
        }
        //对焦触发器设置为空闲状态
        previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
        if (isVideoFous) {
            previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
        } else {
            previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            setPreviewBright();
        }
        previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);

    }

    //调节亮度
    private void setPreviewBright() {
        //设置自动曝光帧率范围 调整fps范围和修复暗预览
        previewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, getRange2());
        //需要设置曝光模式在非锁定状态下或自动曝光模式下，才能起作用。(锁定曝光，手动调曝光 不起作用)
        //previewBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
        //previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
    }

    private Range<Integer> getRange() {
        if (cameraCharacter == null) {
            return null;
        }
        Range<Integer>[] ranges = cameraCharacter.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
        if (ranges == null) {
            return null;
        }
        Range<Integer> result = null;
        for (Range<Integer> range : ranges) {
            int upper = range.getUpper();
            //  帧率不能太低，大于10
            if (upper >= 10) {
                if (result == null || upper < result.getUpper().intValue()) {
                    result = range;
                }
            }
        }
        return result;
    }

    private Range<Integer> getRange2() {
        if (cameraCharacter == null) {
            return null;
        }
        Range<Integer>[] ranges = cameraCharacter.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
        if (ranges == null) {
            return null;
        }
        Range<Integer> result = null;

        for (Range<Integer> range : ranges) {
            //帧率不能太低，大于10
            if (range.getLower() < 10) {
                continue;
            }
            if (result == null) {
                result = range;
                continue;
            }
            //FPS下限小于15，弱光时能保证足够曝光时间，提高亮度。
            // range范围跨度越大越好，光源足够时FPS较高，预览更流畅，
            // 光源不够时FPS较低，亮度更好。
            if (range.getLower() <= 15 && (range.getUpper() - range.getLower())
                    > (result.getUpper() - result.getLower())) {
                result = range;
            }

        }
        return result;
    }

    //设置曝光 补偿
    private void set() {
        previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
        previewBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
        previewBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 6);
        //
        Range<Integer> range1 = cameraCharacter.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
        int maxmax = range1.getUpper();
        int minmin = range1.getLower();
        int all = (-minmin) + maxmax;
        int time = 100 / all;
        //int ae = ((i / time) - maxmax) > maxmax ? maxmax : ((i / time) - maxmax) < minmin ? minmin : ((i / time) - maxmax);
        //previewBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, ae);

    }

    //切换灯光
    protected void onCameraSwithLight() {
        isLight = !isLight;
        if (isLight) {
            previewBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
        } else {
            previewBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
        }
        try {
            cameraSession.setRepeatingRequest(previewBuilder.build(), null, backgroundHandler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //切换摄像头
    protected void onCameraSwitch() {
        if (cameraCount <= 1) {
            d("不支持 切换摄像头");
        }
        boolean isFront = !isCameraBack;
        onCameraClose();
        MediaRecorderManager.getInstance().setMediaWork(4);
        isCameraBack = isFront;
        initCamera(context);
    }

    private CameraRecordVideo cameraRecordVideo;

    //设置视频录制
    protected void onRecorderStart(Activity activity, String videoPath) {
        closeSession();
        cameraRecordVideo = new CameraRecordVideo();
        cameraRecordVideo.setBackgroundHandler(backgroundHandler);
        cameraRecordVideo.setVideoSzie(cameraCharacter, previewSize);
        //屏幕方向 0,1,2,3
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        try {
            previewBuilder = cameraRecordVideo.getCaptureRequest(cameraDevice, getSurface());
            cameraRecordVideo.onRecorderStart(previewBuilder, rotation,
                    cameraCharacter, cameraDevice, previewBack, videoPath);
            isVideoFous = true;
        } catch (CameraAccessException e) {
            e.printStackTrace();
            if (backgroundHandler != null) {
                backgroundHandler.sendEmptyMessage(31);
            }
        }
    }

    private CameraTakePhoto cameraTakePhoto;

    // 拍照
    protected void onTakePicture(String imagePath) {
        if (null == cameraDevice) {
            return;
        }
        try {
            d("拍照开始");
            cameraTakePhoto.setImagePath(imagePath);
            cameraTakePhoto.onTakePhoto(cameraDevice, isCameraBack, zoom,
                    cameraSession, takeCallback);
        } catch (CameraAccessException e) {
            e.printStackTrace();
            d("拍照开始错误:" + e.getMessage());
        }

    }

    private TakeCallback takeCallback = new TakeCallback();

    //这个回调接口用于拍照结束时重启预览，因为拍照会导致预览停止
    class TakeCallback extends CameraCaptureSession.CaptureCallback {
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
            //拍完照unLockFocus，继续预览

            //构建失能AF的请求
            //previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            //闪光灯重置为未开启状态
            //previewBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
            //继续开启预览
            //cameraSession.setRepeatingRequest(previewRequest, null, backgroundHandler);

        }
    }

    //相机开启回调
    class StateCallback extends CameraDevice.StateCallback {

        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            //打开摄像头
            d("打开摄像头成功 开始预览");
            cameraDevice = camera;
            try {
                closeSession();
                //创建预览需要的CaptureRequest.Builder
                previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                previewBuilder.addTarget(getSurface());
                //
                cameraTakePhoto = new CameraTakePhoto();
                cameraTakePhoto.setBackgroundHandler(backgroundHandler);
                cameraTakePhoto.setPhotSize(cameraCharacter, previewSize);
                cameraTakePhoto.setImageReader();
                Surface imageReaderSurface = cameraTakePhoto.getImageReaderSurface();
                //previewBuilder.addTarget(imageReaderSurface);
                //设置聚焦模式
                onAutoFocus(false);
                //预览请求和拍照请求
                cameraDevice.createCaptureSession(Arrays.asList(getSurface(), imageReaderSurface),
                        previewBack, backgroundHandler);
                if (backgroundHandler != null) {
                    backgroundHandler.sendEmptyMessage(1);
                }
            } catch (CameraAccessException e) {
                e.printStackTrace();
                onCameraError(4, "预览失败:" + e.getMessage());
            }


        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            //相机设备失去连接(不能继续使用)时回调此方法，
            //同时当打开相机失败时也会调用此方法而不会调用onOpened()
            //可在此关闭相机，清除CameraDevice引用
            if (camera == null) {
                return;
            }
            onCameraClose();
            d("相机关闭摄像头 onDisconnected");
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            //发生错误
            //相机发生错误时调用此方法
            onDisconnected(camera);
            d("相机发生错误 onCameraError " + error);
        }
    }

    //相机预览
    private CameraCaptureBack previewBack = new CameraCaptureBack();

    class CameraCaptureBack extends CameraCaptureSession.StateCallback {

        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            if (cameraDevice == null) {
                return;
            }
            // 当摄像头已经准备好时，开始显示预览
            cameraSession = session;
            previewRequest = previewBuilder.build();
            //设置聚焦模式
            //previewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
            try {
                cameraSession.setRepeatingRequest(previewRequest, null, backgroundHandler);
                d("相机配置完成");
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
            d("相机配置失败");
        }
    }

    //true 视频对焦点
    private boolean isVideoFous;
    private FocusCallback focusCallback = new FocusCallback();

    //聚焦监听
    class FocusCallback extends CameraCaptureSession.CaptureCallback {
        @Override
        public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request,
                                        @NonNull CaptureResult partialResult) {
            //process(partialResult);
        }

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request,
                                       @NonNull TotalCaptureResult result) {
            cameraSession = session;
            d("聚焦回调" + " afState:完成");
            process(result);
        }

        private void process(CaptureResult result) {
            // 等待锁定的状态, 某些设备完成锁定后CONTROL_AF_STATE可能为null
            Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
            if (null == afState) {
                return;
            }
            d("聚焦回调" + " afState:" + afState);
            switch (afState) {
                case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
                    //控制自动对焦状态锁定
                case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
                    //控制自动对焦状态未锁定
                    d("聚焦回调-对焦完成" + " afState:" + afState);
                    try {
                        cameraSession.setRepeatingRequest(previewBuilder.build(), null, backgroundHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                    break;
            }

            //onAutoFocus(false);
            /*try {
                cameraSession.setRepeatingRequest(previewBuilder.build(), null, backgroundHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
                d("聚焦回调出错" + e.getMessage());
            }*/
        }

        //人脸聚焦？
        private void process2(CaptureResult result) {
            Face[] cameraFaces = result.get(CaptureResult.STATISTICS_FACES);
            d("人脸聚焦？");
            if (cameraFaces == null) {
                return;
            }
            if (cameraFaces.length == 0) {
                return;
            }
            Rect faceRect = new Rect(cameraFaces[0].getBounds().left, cameraFaces[0].getBounds().top,
                    cameraFaces[0].getBounds().right, cameraFaces[0].getBounds().bottom);
            d("人脸聚焦？" + faceRect.toString());
        }
    }

    protected void onHandleMessage(Message msg) {
    }

    //1：预览 20：拍照写入成功 21：拍照写入失败 31:录制视频错误
    class HandlerCamera extends Handler {
        public HandlerCamera(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            onHandleMessage(msg);
        }
    }

    protected void d(String value) {
        MLog.e(tag, value);
    }
}
